package com.dong.mjblog.util;

import com.drew.imaging.ImageMetadataReader;
import com.drew.imaging.ImageProcessingException;
import com.drew.metadata.Metadata;
import com.drew.metadata.MetadataException;
import com.drew.metadata.exif.ExifIFD0Directory;
import lombok.extern.slf4j.Slf4j;

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;

/**
 * @Author:dxf
 * @Date:2020/12/6-12-06 21:43
 */
@Slf4j
public class ImageUtil {

    //根据图片的exif属性旋转图片并覆盖原图
    public static File rotate(File sourceFile){
        if(sourceFile.exists()){
            try {
                // ImageIO 支持的图片类型 : [BMP, bmp, jpg, JPG, wbmp, jpeg, png, PNG, JPEG, WBMP, GIF, gif]
                String types = Arrays.toString(ImageIO.getReaderFormatNames());
                String suffix = null;
                // 获取图片后缀
                if(sourceFile.getName().contains(".")) {
                    suffix = sourceFile.getName().substring(sourceFile.getName().lastIndexOf(".") + 1).toLowerCase();
                }// 类型和图片后缀全部小写，然后判断后缀是否合法
                if(suffix == null || !types.toLowerCase().contains(suffix)){
                    //类型不支持
                    return null;
                }

                // 将图片保存在原目录并加上前缀
                String p = sourceFile.getPath();

                if(suffix.equals("jpg") || suffix.equals("jpeg")){
                    //根据exif属性旋转图片

                    Metadata metadata = ImageMetadataReader.readMetadata(sourceFile);
                    if(metadata!=null){
                        //ExifIFD0Directory directory=metadata.getDirectory(ExifIFD0Directory.class); //metadata-extractor2.6.2
                        ExifIFD0Directory directory= metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);//metadata-extractor2.11.0

                        if(directory!=null && directory.containsTag(ExifIFD0Directory.TAG_ORIENTATION)){
                            int orientation=directory.getInt(ExifIFD0Directory.TAG_ORIENTATION);

                            int turn=0;
                            if(orientation==3)
                            {
                                turn=180;
                            }
                            else if(orientation==6)
                            {
                                turn=90;
                            }
                            else if(orientation==8)
                            {
                                turn=270;
                            }

                            if(turn>0){
                                BufferedImage src = ImageIO.read(sourceFile);
                                BufferedImage des = rotate(src, turn);
                                ImageIO.write(des,"jpg",sourceFile);
                            }
                        }

                    }
                }
            }catch (ImageProcessingException | MetadataException e) {
                // TODO Auto-generated catch block
                log.error("图片旋转出错",e);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return sourceFile;
        }
        return null;
    }

    public static File thumbnailImage(File sourceFile,int w,int h,String prevfix,String type){
        if(sourceFile.exists()){
            try {
                // ImageIO 支持的图片类型 : [BMP, bmp, jpg, JPG, wbmp, jpeg, png, PNG, JPEG, WBMP, GIF, gif]
                String types = Arrays.toString(ImageIO.getReaderFormatNames());
                String suffix = null;
                // 获取图片后缀
                if(sourceFile.getName().contains(".")) {
                    suffix = sourceFile.getName().substring(sourceFile.getName().lastIndexOf(".") + 1).toLowerCase();
                }// 类型和图片后缀全部小写，然后判断后缀是否合法
                if(suffix == null || !types.toLowerCase().contains(suffix)){
                    //类型不支持
                    return null;
                }

                // 将图片保存在原目录并加上前缀
                String p = sourceFile.getPath();
                File destFile=new File(p.substring(0,p.lastIndexOf(File.separator)) + File.separator + prevfix +sourceFile.getName());


                if(suffix.equals("jpg") || suffix.equals("jpeg")){
                    //根据exif属性旋转图片
                    try {
                        Metadata metadata = ImageMetadataReader.readMetadata(sourceFile);
                        if(metadata!=null){
                            ExifIFD0Directory directory= metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);

                            if(directory!=null && directory.containsTag(ExifIFD0Directory.TAG_ORIENTATION)){
                                int orientation=directory.getInt(ExifIFD0Directory.TAG_ORIENTATION);

                                int turn=0;
                                if(orientation==3)
                                {
                                    turn=180;
                                }
                                else if(orientation==6)
                                {
                                    turn=90;
                                }
                                else if(orientation==8)
                                {
                                    turn=270;
                                }

                                if(turn>0){
                                    BufferedImage src = ImageIO.read(sourceFile);
                                    BufferedImage des = rotate(src, turn);
                                    ImageIO.write(des,"jpg",destFile);
                                    sourceFile=destFile;

                                }
                            }


                        }


                    } catch (ImageProcessingException | MetadataException e) {
                        // TODO Auto-generated catch block
                        log.error("生成缩略图出错",e);
                    }
                }

                Image img = ImageIO.read(sourceFile);
                int width = img.getWidth(null);
                int height = img.getHeight(null);


                if(type==null || type.equals("auto")){//宽度及高度允许自适应
                    // 根据原图与要求的缩略图比例，找到最合适的缩略图比例

                    if((width*1.0)/w < (height*1.0)/h){
                        h = Integer.parseInt(new java.text.DecimalFormat("0").format(height * w/(width*1.0)));

                    } else {
                        w = Integer.parseInt(new java.text.DecimalFormat("0").format(width * h/(height*1.0)));

                    }

                    BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
                    Graphics g = bi.getGraphics();
                    g.drawImage(img, 0, 0, w, h, Color.LIGHT_GRAY, null);
                    g.dispose();

                    ImageIO.write(bi, suffix,destFile );
                    return destFile;

                }else if(type.equals("cut")){//裁切多余的部分

                    double destRatio=(w*1.0)/(h*1.0);
                    double srcRatio=(width*1.0)/(height*1.0);

                    int x=0,y=0,cutWidth=0,cutHeight=0;

                    if(destRatio>=srcRatio){
                        x=0;
                        y=(int)Math.rint((height-width/destRatio)/2);
                        cutWidth=width;
                        cutHeight=(int)Math.rint(width/destRatio);
                    }else{
                        x=(int)Math.rint((width-height*destRatio)/2);
                        y=0;
                        cutWidth=(int)Math.rint(height*destRatio);
                        cutHeight=height;
                    }

                    //System.out.println(x+","+y+","+cutWidth+","+cutHeight);

                    Rectangle rect=new Rectangle(x, y, cutWidth, cutHeight);
                    FileInputStream fis = new FileInputStream(sourceFile);
                    ImageInputStream iis = ImageIO.createImageInputStream(fis);;
                    ImageReader reader = ImageIO.getImageReadersBySuffix(suffix).next();
                    reader.setInput(iis,true);
                    ImageReadParam param = reader.getDefaultReadParam();
                    param.setSourceRegion(rect);
                    BufferedImage cutImg = reader.read(0, param);

                    BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);

                    Graphics g = bi.getGraphics();
                    g.drawImage(cutImg, 0, 0, w, h, Color.WHITE, null);

                    g.dispose();
                    ImageIO.write(bi, suffix,destFile);
                    fis.close();



                    return destFile;
                }else if(type.equals("fill")){//不足的部分填充

                    double destRatio=(w*1.0)/(h*1.0);
                    double srcRatio=(width*1.0)/(height*1.0);
                    int x=0,y=0,copyWidth=0,copyHeight=0;
                    if(destRatio>=srcRatio){
                        x=(int)Math.rint((w-h*srcRatio)/2);//(200-75)/2=62.5=63

                        y=0;
                        copyWidth=(int)Math.rint(h*srcRatio);
                        copyHeight=h;

                    }else{
                        x=0;
                        y=(int)Math.rint((h-w/srcRatio)/2);
                        copyWidth=w;
                        copyHeight=(int)Math.rint(w/srcRatio);

                    }

                    BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);

                    Graphics g = bi.getGraphics();
                    g.drawImage(img, x, y, copyWidth, copyHeight, Color.WHITE, null);

                    g.dispose();
                    ImageIO.write(bi, suffix,destFile);

                    return destFile;
                }else{
                    return null;
                }


            } catch (IOException e) {
                log.error("生成缩略图出错",e);
                return null;
            }
        }else{
            return null;
        }
    }


    public static BufferedImage rotate(Image src, int angel) {
        int src_width = src.getWidth(null);
        int src_height = src.getHeight(null);
        // calculate the new image size
        Rectangle rect_des = calcRotatedSize(new Rectangle(new Dimension(
                src_width, src_height)), angel);

        BufferedImage res = null;
        res = new BufferedImage(rect_des.width, rect_des.height,
                BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = res.createGraphics();
        // transform
        g2.translate((rect_des.width - src_width) / 2,
                (rect_des.height - src_height) / 2);
        g2.rotate(Math.toRadians(angel), (float)src_width / 2, (float)src_height / 2);

        g2.drawImage(src, null, null);
        return res;
    }

    private static Rectangle calcRotatedSize(Rectangle src, int angel) {
        // if angel is greater than 90 degree, we need to do some conversion
        if (angel >= 90) {
            if(angel / 90 % 2 == 1){
                int temp = src.height;
                src.height = src.width;
                src.width = temp;
            }
            angel = angel % 90;
        }

        double r = Math.sqrt(src.height * src.height + src.width * src.width) / 2;
        double len = 2 * Math.sin(Math.toRadians(angel) / 2) * r;
        double angel_alpha = (Math.PI - Math.toRadians(angel)) / 2;
        double angel_dalta_width = Math.atan((double) src.height / src.width);
        double angel_dalta_height = Math.atan((double) src.width / src.height);

        int len_dalta_width = (int) (len * Math.cos(Math.PI - angel_alpha
                - angel_dalta_width));
        int len_dalta_height = (int) (len * Math.cos(Math.PI - angel_alpha
                - angel_dalta_height));
        int des_width = src.width + len_dalta_width * 2;
        int des_height = src.height + len_dalta_height * 2;
        return new Rectangle(new Dimension(des_width, des_height));
    }

    /**
     * @param args
     * @throws IOException
     * @throws ImageProcessingException
     * @throws MetadataException
     */
    public static void main(String[] args) throws ImageProcessingException, IOException, MetadataException {
        // TODO Auto-generated method stub



    }
}